package bing.web.view.controller;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;

import bing.search.common.ClusterNode;
import bing.search.common.Document;
import bing.search.common.Index;
import bing.search.common.IndexTypeField;
import bing.search.es.ClusterService;
import bing.search.es.EsUtils;
import bing.search.es.IndexService;
import bing.search.hbase.HbaseUtils;
import bing.web.common.RequestResultType;
import bing.web.view.pojo.ClusterBean;
import bing.web.view.pojo.PageBean;

@Controller
@RequestMapping("/es")
public class EsController2 {

	static final Logger log = LoggerFactory.getLogger(EsController2.class);

	private final int pageNum = 1;
	private final int pageSize = 3;
	
	private HbaseUtils hbaseUtils = null;
	@Autowired
	private IndexService indexService;
	@Autowired
	private ClusterService clusterService;
	
	public static String INDEX_PATH = "index";

	private HbaseUtils getHbaseUtils() {
		if(hbaseUtils == null) {
			hbaseUtils = new HbaseUtils();
		}
		return hbaseUtils;
	}
	
	@ResponseBody
	@RequestMapping(value = "/createIndex", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
	public String createIndex(HttpServletRequest request){
		String indexName = request.getParameter("indexName");
		String shardsNum = request.getParameter("shardsNum");
		String replicasNum = request.getParameter("replicasNum");
		if(StringUtils.isEmpty(indexName)) {
			return RequestResultType.FAILED;
		}
        if(StringUtils.isEmpty(replicasNum)) {
        	return RequestResultType.FAILED;
		}
		try {
			//index.createDocumentIndex();//创建默认索引和类型
			
			indexService.createIndex(indexName, shardsNum, replicasNum);
		} catch (Exception e) {
			e.printStackTrace();
			return RequestResultType.FAILED;
		}
		return RequestResultType.SUCCESS;
	}
	
	@ResponseBody
	@RequestMapping(value = "/loadAllIndices", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
	public List<Index> loadAllIndices(HttpServletRequest request){
		
		List<Index> indices = Lists.newArrayList();
		try {
			for(String name : indexService.loadAllIndices()) {
				Index index = new Index();
				index.setName(name);
				indices.add(index);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return indices;
	}
	
	@ResponseBody
	@RequestMapping(value = "/loadIndexByName", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
	public String loadIndexByName(HttpServletRequest request){
		String indexName = request.getParameter("indexName");
		try {
			return indexService.loadIndexByName(indexName);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	@ResponseBody
	@RequestMapping(value = "/searchIndexByName", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
	public PageBean<Index> searchIndexByName(HttpServletRequest request){
		
		String indexName = request.getParameter("indexName");
		Map<String, Object> result = indexService.searchIndexByName(indexName, (pageNum - 1) * pageSize, pageSize);
		
		PageBean<Index> page= new PageBean<Index>();
		int count = Integer.parseInt(result.get("count").toString());
		List<Index> indexList = (List<Index>) result.get("dataList");
		page.setDataList(indexList);
		page.setSumRows(count);
		return page;
	}
	
	@ResponseBody
	@RequestMapping(value = "/deleteIndex", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
	public String deleteIndex(HttpServletRequest request){
		String indexName = request.getParameter("indexName");
		boolean result = indexService.deleteIndexByName(indexName);
		
		if(result) {
			return RequestResultType.SUCCESS;
		}
		return RequestResultType.FAILED;
	}
	
	@ResponseBody
	@RequestMapping(value = "/createIndexType", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
	public String createIndexType(HttpServletRequest request){
		String indexName = request.getParameter("indexList");
		String typeName = request.getParameter("typeName");
		String typeSettings = request.getParameter("typeSettings");
		if(StringUtils.isEmpty(indexName)) {
			return "failed";
		}
		if(StringUtils.isEmpty(typeName)) {
        	return "failed";
		}
        if(StringUtils.isEmpty(typeSettings)) {
        	return "failed";
		}
		
        
		try {
			ObjectMapper mapper=new ObjectMapper();
			JsonNode topNode = mapper.readTree(typeSettings);
			Iterator<String> topFields = topNode.fieldNames();
			
			List<IndexTypeField> settings=Lists.newArrayList();
			while(topFields.hasNext()) {
				IndexTypeField indexTypeField = new IndexTypeField();
				String fieldName=topFields.next();
				
				indexTypeField.setFieldName(fieldName);
				//System.out.println(fieldName);
				JsonNode node = topNode.get(fieldName);
				
				Iterator<String> fields=node.fieldNames();
				while(fields.hasNext()) {
					String field=fields.next();
					indexTypeField.addSetting(field, node.get(field).asText());
					//System.out.println(tp+" : "+node.get(tp).asText());
				}
				
				settings.add(indexTypeField);
			}
			
			indexService.createIndexType(indexName, typeName, settings);
			return RequestResultType.SUCCESS;
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return RequestResultType.FAILED;
	}
	
	//@ResponseBody  
	//@RequestMapping(value = "/addIndex.do", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
	public String addIndex() throws Exception {
		System.out.println("create index.");
		try {
			indexService.addIndex();
		} catch (Exception e) {
			e.printStackTrace();
			return "failed";
		}
		return "/create.jsp";
	}
	
	@ResponseBody
	@RequestMapping(value = "/search", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
	public PageBean<Document> searchArticle(HttpServletRequest request) throws IOException {
		request.setCharacterEncoding("utf-8");
		String keywords = request.getParameter("keywords");
		keywords = new String(keywords.getBytes("iso8859-1"),"utf-8");
		System.out.println("search: "+keywords);
		

		Map<String, Object> map = EsUtils.search(keywords, IndexService.INDEX_NAME, IndexService.INDEX_TYPE, (pageNum - 1) * pageSize,
				pageSize);
		int count = Integer.parseInt(map.get("count").toString());
		List<Document> articleList = (List<Document>) map.get("dataList");
        
		PageBean<Document> page =new PageBean<Document>();
		page.setDataList(articleList);
		page.setSumRows(count);
		return page;
	}

	// 查看文档的详细信息
	//@ResponseBody
	//@RequestMapping(value = "/loadDocById", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
	public Document loadDocById(HttpServletRequest request) throws IOException {
		//这里的查询是直接从hbase中查询一条字符串出来，做拆分封装，这里要求protobuffer
		String rowKey=request.getParameter("docId");
		Document doc =this.getHbaseUtils().get(HbaseUtils.DOCUMENT_TABLE_NAME, rowKey);
		return doc;
	}
	
	@ResponseBody
	@RequestMapping(value = "/loadClusterInfo", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
	public ClusterBean loadClusterInfo() {
		Map<String, Object> clusterInfo = clusterService.loadClusterInfo();
		
		ClusterBean cluster =new ClusterBean();
		cluster.setName(clusterInfo.get("clusterName").toString());
		cluster.setHealthStatus(clusterInfo.get("clusterHealthStatus").toString());
		cluster.setNodeList((List<ClusterNode>)clusterInfo.get("clusterNodes"));
		return cluster;
	}
	
	@ResponseBody
	@RequestMapping(value = "/importFileData", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
	public ClusterBean importFileData() {
		Map<String, Object> clusterInfo = clusterService.loadClusterInfo();
		
		ClusterBean cluster =new ClusterBean();
		cluster.setName(clusterInfo.get("clusterName").toString());
		cluster.setHealthStatus(clusterInfo.get("clusterHealthStatus").toString());
		cluster.setNodeList((List<ClusterNode>)clusterInfo.get("clusterNodes"));
		return cluster;
	}
}
